// RequestThreadPool.cpp : implementation file
//

#include "stdafx.h"
#include "kwservercore.h"
#include "RequestThreadPool.h"
#include "BaseRequestHandler.h"
#include "RequestThread.h"

#include "CommonLib\Guard.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CRequestThreadPool

IMPLEMENT_DYNCREATE(CRequestThreadPool, CWinThread)

	CRequestThreadPool::CRequestThreadPool()
{
	m_bAutoDelete = FALSE;
}

CRequestThreadPool::~CRequestThreadPool()
{
}

BOOL CRequestThreadPool::InitInstance()
{
	// TODO:  perform and per-thread initialization here
	return TRUE;
}

int CRequestThreadPool::ExitInstance()
{
	// TODO:  perform any per-thread cleanup here
	return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CRequestThreadPool, CWinThread)
	//{{AFX_MSG_MAP(CRequestThreadPool)
	// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
	ON_THREAD_MESSAGE(WM_APP_REQUESTTHREADEXITED, OnRequestThreadExited)
	ON_THREAD_MESSAGE(WM_APP_EXITTHREAD, OnExitThread)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRequestThreadPool message handlers

CRequestThreadPool * CRequestThreadPool::m_pInstance = NULL;

CRequestThreadPool * CRequestThreadPool::Instance()
{
	if (m_pInstance == NULL)
	{
		m_pInstance = (CRequestThreadPool *)AfxBeginThread(RUNTIME_CLASS(CRequestThreadPool), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
		VERIFY(m_pInstance->ResumeThread());
	}

	return m_pInstance;
}

void CRequestThreadPool::DeleteInstance()
{
	if (m_pInstance) delete m_pInstance;

	m_pInstance = NULL;
}

void CRequestThreadPool::AddRequest(BaseRequestHandler * pHandler)
{
	Guard guard(&m_mutexRequestThreads);

	RequestThread * pRequestThread = new RequestThread(pHandler);
	m_RequestThreads.push_back(pRequestThread);
	pRequestThread->CreateThread();
}

LRESULT CRequestThreadPool::OnRequestThreadExited(WPARAM wParam, LPARAM lParam)
{
	Guard guard(&m_mutexRequestThreads);

	RequestThread * pRequestThread = (RequestThread *)wParam;
	m_RequestThreads.erase(std::remove(m_RequestThreads.begin(), m_RequestThreads.end(), pRequestThread), m_RequestThreads.end());
	pRequestThread->Wait();
	delete pRequestThread;

	return 0;
}

LRESULT CRequestThreadPool::OnExitThread(WPARAM wParam, LPARAM lParam)
{
	Guard guard(&m_mutexRequestThreads);

	std::list<RequestThread *>::const_iterator iter;
	for (iter = m_RequestThreads.begin();iter != m_RequestThreads.end();++iter)
	{
		RequestThread * pRequestThread = *iter;
		pRequestThread->Wait();
	}

	PostQuitMessage(0);

	return 0;
}